#ifndef DATABASEINTERFACE_H
#define DATABASEINTERFACE_H

#include <QObject>
#include <QList>
#include <QCoreApplication>
#include <QString>
#include <QtSql/QSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QMap>
#include <QMetaEnum>
#include <QString>
#include <QDebug>
#include <QtSql/QSqlError>
#include <QtSql/QSqlDriver>
#include <QtSql/QSqlRecord>
#include <QDir>
#include "KylinDaqCommon.h"

class DataBaseInterface:public QObject
{
    Q_OBJECT
public:
    enum SqliteDataType
    {
        INTEGER,
        REAL,
        TEXT,
        BLOB 
    };
    Q_ENUM(SqliteDataType)
    /**
     * @brief 使用的数据库驱动名 
     */
    static constexpr const char* s_sqliteName = "QSQLITE";
    static const int32_t s_lineNumberDividingLine = 100;
private:
    /**
     * @brief 数据库文件夹路径
     * 
     */
    QString m_fileFolderPath;
    /**
     * @brief 数据库名
     * 
     */
    QString m_dataBaseName;
    /**
     * @brief 连接名
     * 
     */
    QString m_connectName;
    /**
     * @brief 数据库对象
     * 
     */
    QSqlDatabase  m_db;
    /**
     * @brief 单例
     * 
     */
    static QScopedPointer<DataBaseInterface> ms_instance;
public:
    /**
     * @brief 单例函数
     * 
     * @return DataBaseInterface* 
     */
    static DataBaseInterface *instance(void);
    /**
     * @brief 创建数据表
     * 
     * @param createString 创建命令
     * @return true 创建成功
     * @return false 创建失败
     */
    bool createTable(const QString &createString);
    /**
     * @brief 创建数据表
     * 
     * @param tableName 表名
     * @param keyType 表中字段
     * @return true 创建成功
     * @return false 创建失败
     */
    bool createTable(const QString &tableName, const QMap<QString,SqliteDataType> &keyType);
    /**
     * @brief 检测表是否存在
     * 
     * @param tableName 表名
     * @return true 表存在
     * @return false 表不存在
     */
    bool existTable(const QString &tableName);
    /**
     * @brief 检测数据库是否存在
     * 
     * @return true 数据库存在
     * @return false 数据库不存在
     */
    bool existDataBase();
    /**
     * @brief 向表中写入数据
     * 
     * @param tableName 表名
     * @param key 键
     * @param value 值
     * @return true 写入成功
     * @return false 写入失败
     */
    bool writeRow(const QString &tableName, const QList<QString> &key, const QList<QList<QVariant>> &value);
    /**
     * @brief 向表中写入数据
     * 
     * @param tableName 表名
     * @param keyValue 键值对
     * @return true 写入成功
     * @return false 写入失败
     */
    bool writeRow(const QString &tableName, const QMap<QString,QVariant> &keyValue);
    /**
     * @brief 从表中读取数据
     * 
     * @param tableName 表名
     * @param key 键
     * @param maxRowNum 最大读取行数
     * @return QList<QList<QVariant>> 读取结果
     */
    QList<QList<QVariant>> readRow(const QString &tableName ,const QList<QString> &key,const int &maxRowNum);
    /**
     * @brief 从表中删除数据
     * 
     * @param tableName 表名
     * @param key 键
     * @param value 值
     * @return true 删除成功
     * @return false 删除失败
     */
    bool deleteRow(const QString &tableName, const QList<QString> &key, const QList<QList<QVariant>> &value);
    /**
     * @brief 更新表中数据
     * 
     * @param tableName 表名
     * @param constraintkey 更新的约束键
     * @param constraintValue 更新的约束值
     * @param key 更新键
     * @param value 更新值
     * @return true 更新成功
     * @return false 更新失败
     */
    bool updateRow(const QString &tableName, const QList<QString> &constraintkey, const QList<QList<QVariant>> &constraintValue, const QList<QString> &key, const QList<QList<QVariant>> &value);
    /**
     * @brief 替换表中数据
     * 
     * @param tableName 表名
     * @param key 键
     * @param value 值
     * @return true 替换成功
     * @return false 替换失败
     */
    bool replaceRow(const QString &tableName, const QList<QString> &key, const QList<QList<QVariant>> &value);
    /**
     * @brief 删除表中数据
     * 
     * @param tableName 表名
     * @param key 键
     * @param maxRow 最大保留行数
     * @return true 删除成功
     * @return false 删除失败
     */
    bool deleteMaxRow(const QString &tableName, const QString &key, const qlonglong &maxRow);
    /**
     * @brief 检测表中存在行数
     * 
     * @param tableName 表名
     * @param key 键
     * @param value 值
     * @return qlonglong 存在的行数
     */
    qlonglong existRowNum(const QString &tableName, const QString &key, const QString &value);
    ~DataBaseInterface();
private:
    DataBaseInterface(const QString &fileFolderPath, const QString &dataBaseName,const QString &connectName,QObject *parent=nullptr);
    void checkDir();
};
#endif
